<template>
  <div v-if="getShowDarkModeToggle" :class="getClass" @click="toggleDarkMode">
    <div :class="`${prefixCls}-inner`"></div>
    <SvgIcon size="14" name="sun" />
    <SvgIcon size="14" name="moon" />
  </div>
</template>
<script lang="ts" setup>
  import { computed, unref } from 'vue';
  import { SvgIcon } from '@/components/Icon';
  import { ThemeEnum } from '@/enums/appEnum';
  import { useRootSetting } from '@/hooks/setting/useRootSetting';
  import { useDesign } from '@/hooks/web/useDesign';
  import { updateDarkTheme } from '@/logics/theme/dark';
  import { updateHeaderBgColor, updateSidebarBgColor } from '@/logics/theme/updateBackground';

  const { prefixCls } = useDesign('dark-switch');
  const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();

  const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);

  const getClass = computed(() => [
    prefixCls,
    {
      [`${prefixCls}--dark`]: unref(isDark),
    },
  ]);

  function updateDarkMode(darkMode: ThemeEnum) {
    setDarkMode(darkMode);
    updateDarkTheme(darkMode);
    updateHeaderBgColor();
    updateSidebarBgColor();
  }

  async function toggleDarkMode(event: MouseEvent) {
    const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
    const x = event.clientX;
    const y = event.clientY;
    // 画圆
    const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
    // @ts-ignore
    if (document.startViewTransition == undefined) {
      /** 明亮和暗黑模式核心逻辑 */
      // 定义图标切换变量(true-月亮，false-太阳)
      updateDarkMode(darkMode);
      /** 明亮和暗黑模式核心逻辑 */
    } else {
      // @ts-ignore
      const transition = document.startViewTransition(() => {
        /** 明亮和暗黑模式核心逻辑 */
        // 定义图标切换变量(true-月亮，false-太阳)
        updateDarkMode(darkMode);
        /** 明亮和暗黑模式核心逻辑 */
      });
      await transition.ready;
      const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];
      document.documentElement.animate(
        {
          clipPath: darkMode === 'dark' ? clipPath : [...clipPath].reverse(),
        },
        {
          duration: 300,
          easing: 'ease-in',
          pseudoElement:
            darkMode === 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
        },
      );
    }
  }
</script>
<style lang="less" scoped>
  @prefix-cls: ~'@{namespace}-dark-switch';

  html[data-theme='dark'] {
    .@{prefix-cls} {
      border: 1px solid rgb(196 188 188);
    }
  }

  .@{prefix-cls} {
    display: flex;
    position: relative;
    align-items: center;
    justify-content: space-between;
    width: 50px;
    height: 26px;
    margin-left: auto;
    padding: 0 6px;
    border-radius: 30px;
    background-color: #151515;
    cursor: pointer;

    &-inner {
      position: absolute;
      z-index: 1;
      width: 18px;
      height: 18px;
      transition:
        transform 0.5s,
        background-color 0.5s;
      border-radius: 50%;
      background-color: #fff;
      will-change: transform;
    }

    &--dark {
      .@{prefix-cls}-inner {
        transform: translateX(calc(100% + 2px));
      }
    }
  }
</style>
<style lang="less">
  ::view-transition-old(root),
  ::view-transition-new(root) {
    mix-blend-mode: normal;
    animation: none;
  }
  ::view-transition-old(root) {
    z-index: 9999;
  }
  ::view-transition-new(root) {
    z-index: 1;
  }
  .dark::view-transition-old(root) {
    z-index: 1;
  }
  .dark::view-transition-new(root) {
    z-index: 9999;
  }
</style>
